/**
 * 
 */
package io.potato.ts.sms.impl;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import io.potato.core.util.JsonUtils;
import io.potato.ts.sms.HuaweiSmsClient;
import io.potato.ts.sms.SmsContent;
import io.potato.ts.sms.SmsRequest;
import io.potato.ts.sms.SmsResponse;
import io.potato.ts.sms.SmsResponse.SmsID;
import io.potato.ts.sms.SmsSender;

/**
 * 华为发送短信接口实现
 * @author timl
 * created: 2019年1月8日 下午3:58:37
 */
@Component
@Slf4j
public class HuaweiSmsSender implements SmsSender {
	
	@Autowired(required=false)
	HuaweiSmsClient smsClient;
	
	@Value("${sms.appkey}")
	private String appKey;
	
	@Value("${sms.appsecret}")
	private String appSecret;
	
	@Value("${sms.channel}")
	private String channel;
	
	@Value("${sms.default-sign}")
	private String defaultSign;
	
	@Value("${sms.status-report-url}")
	private String statusReportUrl;

	@Override
	public List<SmsID> batchSendSms(String to, String body, String extendCode, String extendStr, String sign) {
		if (extendCode == null) 
			extendCode = "";
		
		String wwseHeader = buildWsseHeader(appKey, appSecret);
		String from = getFrom(extendCode);
		
		// 内容需要加上短信签名
		body = getSign(sign) + body;
		
		SmsResponse result = this.smsClient.batchSendSms(wwseHeader, from, to, body, extendStr, statusReportUrl);
		//log.debug(result.toString());
		
		return result.getResult();
	}

	@Override
	public List<SmsID> batchSendDiffSms(List<SmsContent> smsList, String extendCode, String extendStr, String sign) {
		
		String wwseHeader = this.buildWsseHeader(appKey, appSecret);
		
		SmsRequest smsRequest = new SmsRequest();
		smsRequest.setFrom(getFrom(extendCode)); 
		smsRequest.setExtend(extendStr);
		smsRequest.setSmsContent(smsList);
		smsRequest.setStatusCallback(statusReportUrl);
		
		// 每条短信附加短信签名
		smsList.forEach(sms -> sms.setBody(getSign(sign) + sms.getBody()));
		String json = JsonUtils.encode(smsRequest);
        try {
            json = URLEncoder.encode(json, "UTF-8");
        } catch (UnsupportedEncodingException e) {

        }
        //log.debug(json);
		
		SmsResponse result = this.smsClient.batchSendDiffSms(wwseHeader, json);
		//log.debug(result.toString());
		return result.getResult();
	}
	
	private String getSign(String sign) {
		if (StringUtils.isEmpty(sign)) {
			sign = "【" + defaultSign + "】";
		} else {
			sign = "【" + sign + "】";
		}
		return sign;
	}
	/**
	 * 发送号码   通道号+拓展码
	 * @param extendCode  拓展码
	 * @return
	 */
	private String getFrom(String extendCode) {
		if (extendCode == null) 
			extendCode = "";
		return channel + extendCode;
	}
	
	/**
	 * 生成华为授权的加密串
	 * @param appKey 短信应用APP KEY
	 * @param appSecret  短信应用 APP Secret
	 * @return
	 */
	private String buildWsseHeader(String appKey, String appSecret) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        String time = sdf.format(new Date());
        String nonce = UUID.randomUUID().toString().replace("-", "");

        byte[] passwordDigest = DigestUtils.sha256(nonce + time + appSecret);
        String hexDigest = Hex.encodeHexString(passwordDigest);
        String passwordDigestBase64Str = Base64.encodeBase64String(hexDigest.getBytes(Charset.forName("utf-8")));
        return String.format(WSSE_HEADER_FORMAT, appKey, passwordDigestBase64Str, nonce, time);
    }
	
	private static final String WSSE_HEADER_FORMAT = "UsernameToken Username=\"%s\",PasswordDigest=\"%s\",Nonce=\"%s\",Created=\"%s\"";

}
